package naive2;

import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.ling.CoreAnnotations.LemmaAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.util.CoreMap;

// converts entity to bag of words representation
//retrieve the json form of a entity, then converts it to its bow representa
//categories in a entity's json file contain a lot word like" a list of " or "places", the former one is meaningless
//note that types and aliases are very useful information

//SIMPLE WAY: not use JSON,just use the row json doc
public class JsonEntity2BoW {
	private StanfordCoreNLP pipeline;
	public JsonEntity2BoW(StanfordCoreNLP pipeline){
		this.pipeline = pipeline;
	}
	
	/*public BoW jentity2bow(JsonEntity je){
		//first check weather their exist a file  stored such parse string,it it does, use that file,else use parse
		String id = 
	}*/
	
	public BoW jentity2bow(JsonEntity je) {
		//long t0 = System.currentTimeMillis();
		
		//System.out.println("before concatenation");
		//long  t1=System.currentTimeMillis();
		
		
		StringBuffer sb = new StringBuffer();
		//String jDoc = "";
		
		//jDoc = jDoc + je.getEntity().getName() + " "; 
		sb.append(je.getEntity().getName());
		sb.append(" ");
		JSONObject jobj = je.getJobj();
		
		if (jobj != null){
			try {
				//jDoc = jDoc + this.getNameString(jobj)+ " ";
				sb.append(this.getNameString(jobj));
				sb.append(" ");
				//jDoc = jDoc + this.getContextString(jobj)+ " ";
				sb.append(this.getContextString(jobj));
				sb.append(" ");
				
				//jDoc = jDoc + this.getKeysString(jobj)+ " ";
				sb.append(this.getKeysString(jobj));
				sb.append(" ");
				
				//jDoc = jDoc + this.getCategoriesString(jobj)+ " ";
				sb.append(this.getCategoriesString(jobj));
				sb.append(" ");
				
				//jDoc = jDoc + this.getAliasString(jobj)+" ";
				sb.append(this.getAliasString(jobj));
				sb.append(" ");
				
				//jDoc = jDoc + this.getAlternativeNames(jobj)+" ";
				sb.append(this.getAlternativeNames(jobj));
				sb.append(" ");
				
				//jDoc = jDoc +this.getTypesString(jobj)+" ";
				sb.append(this.getTypesString(jobj));
				sb.append(" ");
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				System.out.println("we got JSON obj but did not got specific attribute,enitity:"+je.getEntity().getName());
				e.printStackTrace();
			}

		}
		
		//toknize and put lemma into bow
	//	System.out.println("get json string cancatenated!*******************");
	//	long t2 = System.currentTimeMillis();
	//	System.out.println("used time:"+(t2-t1));
		
		String jDoc = sb.toString();
		
	//	System.out.println("Before low case");
		//long t3 = System.currentTimeMillis();
	//	jDoc = jDoc.toLowerCase();
		//long t4 = System.currentTimeMillis();
		//System.out.println("low cased*****************");
		//System.out.println("time used:"+(t4-t3));
		
		
		//System.out.println("before parse");
		//long t5 = System.currentTimeMillis();
	//	Annotation document = new Annotation(jDoc);
	//	pipeline.annotate(document);
	 //   List<CoreMap> sentences = document.get(SentencesAnnotation.class);
	    
	    BoW bow = new BoW();
	  //  for(CoreMap sentence: sentences) {
	        // traversing the words in the current sentence
	        // a CoreLabel is a CoreMap with additional token-specific methods
	    //    for (CoreLabel token: sentence.get(TokensAnnotation.class)) {
	          // this is the text of the token
	         // String word = token.get(TextAnnotation.class);
	          // this is the POS tag of the token
	          //String pos = token.get(PartOfSpeechAnnotation.class);
	      
	      //    String lemma = token.get(LemmaAnnotation.class);
	       //   if( lemma.equals("-LRB-")|| lemma.equals("-RRB-")|| lemma.equals("-lrb-")||lemma.equals("-rrb-")||lemma.equals(",")||lemma.equals(".")){
	        //	  continue;
	         // }
	          // also need to handle when lemma is punctation or "a" "the"
	          
	          
	          //System.out.println("word:"+word+",lemma:"+lemma+",pos:"+pos);
	          
	          //change to its low case, because in json File they are all low cased
	          //lemma = lemma.toLowerCase();
	          //bow.putWord(lemma);
	         
	        //}
	     String[] ss = jDoc.split(" ");
	     for(String s:ss){
	    	 bow.putWord(s);

	      }
	    //System.out.println("after pase***************");
	    //long t6 = System.currentTimeMillis();
	    //System.out.println("time used:"+(t6-t5));
	    
	   // long t7 = System.currentTimeMillis();
	  //  System.out.println("time used for parsing entity:"+(t7-t0));
		
		
		return bow;
	}
	
	public String getNameString(JSONObject jobj) throws JSONException{
		
		String name = jobj.getString("name");
		
		if( name == null){
			return "";
		}
		name = name+" ";
		return name;
	}
	
	public String getKeysString(JSONObject jobj) throws JSONException{
		StringBuffer sb = new StringBuffer();
		sb.append(" ");
		//String keys = "";
		JSONObject keyobj = jobj.getJSONObject("keys");
		if(keyobj!=null){
			for(Object key: keyobj.keySet() ){
			
				//keys = keys + keyobj.getString((String)key)+" ";
				sb.append(keyobj.getString((String)key));
				sb.append(" ");
			
			}
		}
		
		return sb.toString();
		
	}
	
	public String getContextString(JSONObject jobj) throws JSONException{
		
		//String contexts = "";
		StringBuffer sb = new StringBuffer();
		sb.append(" ");
		
		JSONObject conobj = jobj.getJSONObject("contexts");
		//System.out.println("contexts");
		if( conobj!=null ){
			for(Object key: conobj.keySet() ){
			//System.out.println("\t"+(String)key+" freq:"+conobj.getInt((String)key));
				for( int i=0; i<conobj.getInt((String)key);i++){
				//contexts = contexts + (String)key+" ";
					sb.append((String)key);
					sb.append(" ");
				}
			}
		}
		
		return sb.toString();
	}
	
	public String getCategoriesString(JSONObject jobj) throws JSONException{
		//String categories = "";
		StringBuffer sb = new StringBuffer();
		sb.append(" ");
		JSONObject catobj = jobj.getJSONObject("categories");
		//System.out.println("categories");
		if( catobj!=null){
			for(Object key: catobj.keySet() ){
				//System.out.println("\t"+(String)key+" freq:"+catobj.getInt((String)key));
				//categories = categories + (String)key + " ";
				sb.append((String)key);
				sb.append(" ");
			}
		}
		
		return sb.toString();
	}
	//split using /and _
	public String getTypesString(JSONObject jobj) throws JSONException{
		
		//String types = "";
		StringBuffer sb = new StringBuffer();
		sb.append(" ");
		JSONArray tarr = jobj.getJSONArray("types");
		//System.out.println("types:");
		if( (tarr!=null)&&(tarr.length()>0) ){
			for (int i=0;i<tarr.length();i++){
				//System.out.println("\t"+tarr.getString(i));
				String type = tarr.getString(i);
				String[] ss=type.split("/|_");
				for(String s:ss){
					//types = types + s +" ";
					sb.append(s);
					sb.append(" ");
				}
			}
		}
		
		return sb.toString();
	}
	
	public String getAliasString( JSONObject jobj ) throws JSONException{
		
		//String aliases = " ";
		StringBuffer sb = new StringBuffer();
		sb.append(" ");
		JSONObject aobj = jobj.getJSONObject("aliases");
		//System.out.println("aliases");
		if( aobj!=null ){
			for(Object key: aobj.keySet() ){
			
				//System.out.println("\t"+(String)key+" freq:"+aobj.getJSONObject((String)key).getInt("frequency"));
		
				//#TRADEOFF: use freq or not
				for( int i=0; i<aobj.getJSONObject((String)key).getInt("frequency"); i++){
					if ( i> 5){
						break;
					}
					//aliases = aliases + (String)key + " ";
					sb.append((String)key);
					sb.append(" ");
				}
			}
		}
		
		return sb.toString();
	}	
	
	public String getAlternativeNames(JSONObject jobj) throws JSONException{
		//String ans = " ";
		StringBuffer sb = new StringBuffer();
		
		if( !jobj.isNull("alternativeName1")){
			String al1 = jobj.getString("alternativeName1");
		//System.out.println("al1:");
		//System.out.println(al1);
		//if( al1!=null ){
			//ans = ans + al1 + " ";
		 	sb.append(al1);
		 	sb.append(" ");
		//}
		}
		
		
		if( !jobj.isNull("alternativeName2")){
			String al2 = jobj.getString("alternativeName2");
		
		//System.out.println("al2:");
		//if(( al2!=null)){
			//System.out.println(al2);
			//ans = ans + al2 + " ";
			sb.append(al2);
			sb.append(" ");
		//}
		}
		
		if( !jobj.isNull("alternativeNames")){
			JSONArray arr = jobj.getJSONArray("alternativeNames");
			//System.out.println("als:");
			if( (arr!=null)&&(arr.length()>0) ){
				for (int i=0;i<arr.length();i++){
				//System.out.println("\t"+arr.getString(i));
				//ans = ans + arr.getString(i) + " ";
					sb.append(arr.getString(i));
					sb.append(" ");
				}
			}
		}
		
		return sb.toString();
	}
	
	public static void main(String[]args){
		//String s = "aaaa/bb/ccc_dd/eeee/fff_gg/hh";
		
		String s = "weoriu wer powieu    wpeori   wpoeir w      er";
		String[] ss = s.split(" ");
		BoW bow = new BoW();
		
		for ( String a: ss){
			System.out.println(":*"+a);
			bow.putWord(a);
			
		}
		System.out.println(bow);
	}
	
	
}
